package com.zzl.bonds.ticket.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.common.utils.IoUtils;
import com.zzl.bonds.ticket.constant.FileBucketTypeConstant;
import com.zzl.bonds.ticket.constant.StringConstant;
import com.zzl.bonds.ticket.dto.feign.FileInfo;
import com.zzl.bonds.ticket.dto.feign.FileInfoPar;
import com.zzl.bonds.ticket.dto.ticketopen.InvoiceResult;
import com.zzl.bonds.ticket.feign.FileCenterFeign;
import com.zzl.bonds.ticket.service.FileService;
import com.zzl.general.common.exception.SysException;
import com.zzl.general.common.utils.ResponseUtil;
import com.zzl.general.common.utils.Result;
import com.zzl.general.ocr.BdAiUntil;
import com.zzl.general.ocr.constant.InvoiceFileTypeEnum;
import com.zzl.general.ocr.pojo.InvoiceWordsResult;
import com.zzl.general.qcc.QccUntil;
import feign.Response;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import static com.zzl.bonds.ticket.constant.FileBucketTypeConstant.FILE_BUCKET_OPEN_RELATED_FILE;
import static com.zzl.general.common.utils.ResultCode.SUCCESS;

/**
 * @author gull
 * @date 2021-11-09 20:04:58
 */
@Service("fileService")
@Slf4j
@SuppressWarnings("unused")
public class FileServiceImpl implements FileService {
    @Autowired
    @SuppressWarnings("all")
    private FileCenterFeign fileCenterFeign;
    @Autowired
    @SuppressWarnings("all")
    private RabbitTemplate rabbitTemplate;
    @Autowired
    @SuppressWarnings("all")
    private QccUntil qccUntil;
    @Autowired
    @SuppressWarnings("all")
    private BdAiUntil bdAiUntil;


    /**
     * 上传文件
     *
     * @param file 文件流
     */
    @Override
    public void upLoadBusinessInfoFile(MultipartFile file, String type) throws SysException {
       /* BusinessInfoDto businessInfoDto = new BusinessInfoDto();
        BusinessLicenseInfo businessLicenseInfo;
        IDCardResult idCardResult;
        String msg = "图片识别异常";
        String fileBucket;
        //营业执照识别
        try {
            if (FileTypeConstant.IMAGE_TYPE_BUSINESS_LICENSE.getKey().equals(type)) {
                businessLicenseInfo = bdAiUntil.businessLicenseOcr(file.getInputStream());
                businessInfoDto.setBusinessLicenseInfo(businessLicenseInfo);
                if (null == businessLicenseInfo.getWordsResult()) {
                    msg = "营业执照上传不正确，无法识别";
                    throw new SysException(msg);
                }
                fileBucket = FileBucketTypeConstant.FILE_BUCKET_BUSINESS_LICENSE.getKey();
            } else if (FileTypeConstant.IMAGE_TYPE_FRONT_ID_CARD.getKey().equals(type)) {
                //身份证正面识别
                idCardResult = bdAiUntil.idCardOcr(file.getInputStream());
                businessInfoDto.setIdCardResult(idCardResult);
                if (null == idCardResult.getName()) {
                    msg = "身份证正面上传不正确，无法识别";
                    throw new SysException(msg);
                }
                fileBucket = FileBucketTypeConstant.FILE_BUCKET_ID_CARD.getKey();
            } else if (FileTypeConstant.IMAGE_TYPE_BACK_ID_CARD.getKey().equals(type)) {
                //身份证反面识别
                idCardResult = bdAiUntil.idCardOcr(file.getInputStream());
                businessInfoDto.setIdCardResult(idCardResult);
                if (null == idCardResult.getExpiryDate()) {
                    msg = "身份证背面上传不正确，无法识别";
                    throw new SysException(msg);
                }
                fileBucket = FileBucketTypeConstant.FILE_BUCKET_ID_CARD.getKey();
            } else if (FileTypeConstant.FILE_TYPE_AUTHORIZATION_LETTER.getKey().equals(type)) {
                fileBucket = FileBucketTypeConstant.FILE_TYPE_AUTHORIZATION_LETTER.getKey();
            } else {
                msg = "图片类型输入不正确";
                throw new SysException(msg);
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new SysException(msg);
        }
        //上传文件到文件中心
        String objId = upLoadFile(file, fileBucket);
        businessInfoDto.setObjId(objId);
        return businessInfoDto;*/
    }

    /**
     * 手机上传图片
     *
     * @param file     文件
     * @param socketId 唯一标识
     * @return 文件id
     */
    @Override
    public String upLoadFileByMobile(MultipartFile file, String socketId, String type) throws SysException {
      /*  //上传图片并进行ocr识别
        BusinessInfoDto businessInfoDto = upLoadBusinessInfoFile(file, type);
        //发送消息到mq，用于和前端进行socket通信
        sendMsgToMq(socketId, "上传文件成功", businessInfoDto.getObjId(), businessInfoDto);
        return businessInfoDto.getObjId();*/
        return "";
    }

    /**
     * 上传文件
     *
     * @param file   文件对象
     * @param bucket 文件桶
     * @return 文件id
     * @throws SysException 当调用feign时，无返回值或返回失败会抛出这个异常
     */
    @Override
    public String upLoadFile(MultipartFile file, String bucket) throws SysException {
        //上传文件到文件中心
        log.info("上传文件", file, bucket);
        Result result = fileCenterFeign.uploadFileMongo(file, bucket);
        if (result == null) {
            throw new SysException("上传失败！");
        }
        if (SUCCESS.getCode() == result.getCode()) {
            @SuppressWarnings({"rawtypes"})
            Map map = (Map) result.getResult().get(StringConstant.FILE_INFO);
            return (String) map.get(StringConstant.OBJ_ID);
        } else {
            throw new SysException(result.getMsg());
        }
    }

    /**
     * 下载文件
     *
     * @param response 响应对象
     * @param bucket   桶
     * @param objId    文件对象id
     * @param fileName 文件名称
     */
    @Override
    public void downloadFile(HttpServletResponse response, String bucket, String objId, String fileName) {
        log.info("下载文件", fileName);
        if (StringUtils.isEmpty(fileName)) {
            FileInfoPar fileInfoPar = new FileInfoPar();
            fileInfoPar.setBucket(bucket);
            fileInfoPar.setIds(Collections.singletonList(objId));
            Result fileFeignResult = fileCenterFeign.getFileNameByIds(fileInfoPar);
            if (SUCCESS.getCode() != fileFeignResult.getCode()) {
                ResponseUtil.out(response, Result.error("文件服务异常！"));
            }
            Object fileListObj = fileFeignResult.getResult().get("list");
            if (null == fileListObj) {
                ResponseUtil.out(response, Result.error("文件服务异常！"));
            }
            List<FileInfo> fileInfoList = JSON.parseArray(JSON.toJSONString(fileListObj), FileInfo.class);
            if (!CollectionUtils.isEmpty(fileInfoList)) {
                fileName = fileInfoList.get(0).getFileName();
            }
        }
        Response resp = fileCenterFeign.downloadFileMongoAllowAuth(objId, bucket);
        response.setCharacterEncoding("UTF-8");
        // 2.设置文件头：最后一个参数是设置下载文件名
        response.setHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes(), StandardCharsets.ISO_8859_1));
        try {
            IoUtils.copy(resp.body().asInputStream(), response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
            ResponseUtil.out(response, Result.error(e.getMessage()));
        }
    }

    /**
     * 上传发票
     *
     * @param file 文件
     * @return 发票信息
     */
    @Override
    public InvoiceResult uploadInvoiceFile(MultipartFile file) throws SysException {
        InvoiceResult invoiceResult = new InvoiceResult();
        InvoiceFileTypeEnum invoiceFileTypeEnum;
        if (file.getOriginalFilename().endsWith(StringConstant.PDF)) {
            invoiceFileTypeEnum = InvoiceFileTypeEnum.PDF_FILE;
        } else {
            invoiceFileTypeEnum = InvoiceFileTypeEnum.IMAGE;
        }
        //发票识别ocr
        InvoiceWordsResult invoiceWordsResult;
        try {
            invoiceWordsResult = bdAiUntil.invoiceIdentify(file.getInputStream(), invoiceFileTypeEnum);
        } catch (Exception e) {
            throw new SysException("识别发票文件异常");
        }
        if (ObjectUtils.isEmpty(invoiceWordsResult)) {
            throw new SysException("未识别发票文件" + file.getOriginalFilename());
        }
        BeanUtils.copyProperties(invoiceWordsResult, invoiceResult);
        String objId = this.upLoadFile(file, FILE_BUCKET_OPEN_RELATED_FILE.getKey());
        invoiceResult.setObjId(objId);
        return invoiceResult;
    }

}